#include "PlaceChooser.h"

PlaceChooser::PlaceChooser()
{
	Initialized = false;
}

PlaceChooser::~PlaceChooser(void)
{
}

void PlaceChooser::Init(Unidade* base, int Size){
	if(Initialized) return;
	

	Base = mp((base->getTilePosition()).x(), (base->getTilePosition()).y());
	PlaceChooser::SIZE = Size;

	for(int x = -4; x <= 4; ++x){
		for(int y = - 4; y <= 4; ++y){
			Pts.push_back(mp(x,y));
			Constructions[mp(x,y)] = 0;
			Grid[mp(x,y)] = 0;
		}
	}

	random_shuffle(Pts.begin(), Pts.end());
	Initialized = true;
}

bool PlaceChooser::TryConstruct(Ponto Cell, Unidade* Worker, TYPE Building){
	Ponto LimitX = mp(SIZE * Cell.X, SIZE * (Cell.X + 1));
	Ponto LimitY = mp(SIZE * Cell.Y, SIZE * (Cell.Y + 1));
	if(LimitX.first > LimitX.second) swap(LimitX.first, LimitX.second);
	if(LimitY.first > LimitY.second) swap(LimitY.first, LimitY.second);
	

	BWAPI::TilePosition NewPosition;
	for(int i = 0; i < 7; ++i){
		int x = Base.X + LimitX.first + rand() % (LimitX.second - LimitX.first);
		int y = Base.Y + LimitY.first + rand() % (LimitY.second - LimitY.first);
		NewPosition = BWAPI::TilePosition(x, y);
		if(Worker->build(NewPosition, Building)){
			return true;
		}
		
	}

	return false;
}

void PlaceChooser::MakeConstruction(Unidade* Worker, TYPE Building){
	vector<pair<double,Ponto> > notas;
	for(vector<Ponto>::iterator it = Pts.begin(); it != Pts.end(); ++it){
		int Passagens = 1;
		if(Grid.empty() == false){
			map<Ponto,int>::iterator fim = Grid.end();
			--fim;
			Passagens += (*fim).second;
		}
		notas.push_back(mp(Grid[*it]/double(Passagens) + Constructions[*it]/5.0 + (abs((*it).X) + abs((*it).Y))/20.0, *it));
	}

	sort(notas.begin(), notas.end());
	random_shuffle(notas.begin(), notas.begin() + 15);
	for(int i = 0; i < notas.size(); ++i){

		if(TryConstruct(notas[i].Y, Worker, Building)){
			++Constructions[notas[i].second];
			return;
		}
	}
}

void PlaceChooser::Update(set<Unidade*> Units){
	for(SETI it = Units.begin(); Initialized && it != Units.end(); ++it){
		if((*it) == NULL) continue;
		if((*it)->exists() == false) continue;
		if((*it)->getType() != PROBE) continue;
		

		Ponto Pos = mp( ((*it)->getTilePosition()).x() - Base.X, ((*it)->getTilePosition()).y() - Base.Y);
		Pos.X /= SIZE;
		Pos.Y /= SIZE;
		
		int Qtd = Grid[Pos];
		++Qtd;
		Grid[Pos] = Qtd;
	}
}
	
	